/*自身对应的.h文件*/
#include "app_sensor_data.h"

/*程序内部对应的.h文件*/
#include "log.h"
#include "app_sensor_data_struct.h"

/*外部库对应的.h文件*/
#include "drv_db.h"

/*系统.h文件*/
#include <stdio.h>
#include <time.h>
#include <string.h>

/*数据库 地址*/
#define DB_PATH "/root/lvgl_demo/test_db/test.db"
/*数据库 表名*/
#define TABLE_NAME "test"
/*数据库 指针*/
static sqlite3 *g_db;

/***************************************************************
 * Name:	 string_to_time()
 * Input : str 时间字符串
 * Output: void
 * Return: time_t 转换成功 -1转换失败
 * Author: hwl
 * Revise: V1.0
 * Description: 时间字符串转换为time_t
 ***************************************************************/
static time_t string_to_time(const char* str);

/***************************************************************
 * Name:	 sensor_data_db_init()
 * Input : db_path 数据库地址
 * Output: void
 * Return: 数据库指针
 * Author: hwl
 * Revise: V1.0
 * Description: 打开数据库
 ***************************************************************/
static sqlite3* sensor_data_db_init(char* db_path)
{
	/* 打开数据库 */
	sqlite3* db = drv_db_open_db(db_path);
	if(db == NULL)
	{
		return NULL;
	}
	else
	{
		return db;
	}
}

/***************************************************************
 * Name:	 sensor_data_table_find()
 * Input : db 数据库指针 table_name 表名
 * Output: void
 * Return: 0 成功 -1 失败
 * Author: hwl
 * Revise: V1.0
 * Description: 寻找数据表
 ***************************************************************/
static int sensor_data_table_find(sqlite3* db, char* table_name)
{
	db_create_table_params_t* info = drv_db_find_table(db, table_name);

	if(info->col_count == 0)
	{
		return -1;
	}
	else
	{
		drv_db_free_table_info(info);
		return 0;
	}
}

/***************************************************************
 * Name:	 sensor_data_table_init()
 * Input : db 数据库指针 table_name 表名
 * Output: void
 * Return: 0 成功 -1 失败
 * Author: hwl
 * Revise: V1.0
 * Description: 初始化数据表
 ***************************************************************/
static int sensor_data_table_init(sqlite3* db, char* table_name)
{
	// 定义用户表结构
	db_column_definition_t col_def[] = {
		{
			.cons = FEAT_NOT_NULL,
			.col_type = {
				.column_name = "DATE",
				.data_type = SQLITE_TEXT,
				.value.text_value = "'2025-02-22 12:01:02'",
			},
		},
		{
			.cons = FEAT_NOT_NULL,
			.col_type = {
				.column_name = "SN",
				.data_type = SQLITE_TEXT,
				.value.text_value = "'1700000000'",
			},
		},
		{
			.cons = FEAT_NOT_NULL,
			.col_type = {
				.column_name = "TYPE",
				.data_type = SQLITE_TEXT,
				.value.text_value = "'NULL'",
			},
		},
		{
			.cons = FEAT_NOT_NULL,
			.col_type = {
				.column_name = "DATA",
				.data_type = SQLITE_FLOAT,
				.value.float_value = 0.0,
			},
		},
	};

	db_create_table_params_t create_table_param = {
		.col_def = col_def,
		.col_count = sizeof(col_def) / sizeof(db_column_definition_t),
	};

	// 创建表
	char* err_msg = NULL;
	if (drv_db_create_table(db, table_name, &create_table_param) != SQLITE_OK)
	{
		return -1;
	}
	else
	{
		return 0;
	}
}

/***************************************************************
 * Name:	 sensor_data_table_delete()
 * Input : db 数据库指针 table_name 表名
 * Output: void
 * Return: 0 成功 -1 失败
 * Author: hwl
 * Revise: V1.0
 * Description: 删除数据表
 ***************************************************************/
static int sensor_data_table_delete(sqlite3* db, char* table_name)
{
	if (drv_db_delete_table(db, table_name) != SQLITE_OK)
	{
		return -1;
	}
	else 
	{
		return 0;
	}
}

/***************************************************************
 * Name:	 app_sensor_data_add_data()
 * Input : data 插入的数据
 * Output: void
 * Return: 0 成功 -1 失败
 * Author: hwl
 * Revise: V1.0
 * Description: 插入一条传感器数据
 ***************************************************************/
int app_sensor_data_add_data(sensor_data_t* sensor_data)
{
	char date[20];
	sensor_data_get_date(sensor_data, date);

	char sn[11];
	sensor_data_get_sn(sensor_data, sn);

	sensor_type_t type;
	sensor_data_get_type(sensor_data, &type);
	char type_str[10];
	sensor_data_type_to_str(type, type_str);

	float data;
	sensor_data_get_data(sensor_data, &data);

	db_column_value_t col_data[] = {
		[0] = {
			.column_name = "DATE",
			.data_type = SQLITE_TEXT,
			.value.text_value = date,
		},
		[1] = {
			.column_name = "SN",
			.data_type = SQLITE_TEXT,
			.value.text_value = sn,
		},
		[2] = {
			.column_name = "TYPE",
			.data_type = SQLITE_TEXT,
			.value.text_value = type_str,
		},
		[3] = {
			.column_name = "DATA",
			.data_type = SQLITE_FLOAT,
			.value.float_value = data,
		},
	};

	db_line_col_t line_data[] = {
		{
			.col = col_data,
			.col_count = sizeof(col_data) / sizeof(db_column_value_t),
		},
	};

	db_col_insert_param_t add_data = {
		.insert_data = line_data,
		.data_count = sizeof(line_data) / sizeof(db_line_col_t),
	};

	// 在事务中执行批量插入
	return db_col_insert_data(g_db, TABLE_NAME, add_data) == SQLITE_OK ? 0 : -1;
}

/***************************************************************
 * Name:	 app_sensor_data_get_data()
 * Input : param 筛选参数 param_count 参数个数
 * Output: data_list 筛选出来的数据列表 （没有数据=NULL没有数据） 列表长度（没有数据=0）
 * Return: void
 * Author: hwl
 * Revise: V1.0
 * Description: 读取一条传感器数据
 ***************************************************************/
void app_sensor_data_get_data(db_where_condition_t* param, size_t param_count,
															sensor_data_t** data_list, size_t* size)
{
	const size_t col_count = 4;
	const char* col_name[] = {
		"DATE",
		"SN",
		"TYPE",
		"DATA",
	};

	db_select_param filter = {
		.select_columns = (const char**)col_name,
		.column_count = col_count,
		.conditions = param,
		.condition_count = param_count,
	};

	db_result_queue* all_data = db_col_query_data(g_db, TABLE_NAME, filter);

	if (all_data == NULL)
	{
		*data_list = NULL;
		*size = 0;
	}
	else
	{
		size_t buf_size = 5;				//生成空间中包含的个数
		sensor_data_t *buf = NULL;	//生成空间
		size_t count = 0;						//查找到的个数

		/*初始化生成空间*/
		buf = malloc(buf_size * sensor_data_size());
		if (buf == NULL)
		{
			*data_list = NULL;
			*size = 0;
			db_col_select_res_free(all_data);
		}
	
		db_result_node* node = all_data->head;
		while (node != NULL)
		{
			/*空间不够 扩容*/
			if (count >= buf_size)
			{
				buf_size *=2;
				int *tmp = realloc(buf, buf_size * sensor_data_size());
				LOG_DEBUG("realloc more count:%ld buf_size:%ld\n", count, buf_size);
				if (!tmp)
				{
					LOG_DEBUG("ERROR realloc more fail count:%ld buf_size:%ld\n", count, buf_size);

					*data_list = NULL;
					*size = 0;
					db_col_select_res_free(all_data);
					free(buf);
					return;
				}
				else
				{
					buf = (sensor_data_t*)tmp;	//配置为新的地址
				}
			}

			LOG_DEBUG("count:%ld buf_size:%ld\n", count, buf_size);
			/*保存一组数据*/
			for(int i = 0; i < node->column_count; i++)
			{
				if(strcmp(node->columns[i].column_name, "DATE") == 0)	//保存时间
				{
					/*时间转换*/
					time_t t = string_to_time(node->columns[i].value.text_value);
					if (t == (time_t)-1)
					{
						LOG_ERROR("sensor date trans fail\n");

						*data_list = NULL;
						*size = 0;
						db_col_select_res_free(all_data);
						free(buf);
						return;
					}
					else
					{
						sensor_data_set_custom_date(sensor_data_list_col(buf, count), t);
					}
				}
				else if(strcmp(node->columns[i].column_name, "SN") == 0)	//保存SN号
				{
					sensor_data_set_sn(sensor_data_list_col(buf, count), node->columns[i].value.text_value);
				}
				else if(strcmp(node->columns[i].column_name, "TYPE") == 0)	//保存类型
				{
					sensor_type_t type;
					sensor_data_str_to_type(node->columns[i].value.text_value, &type);
					sensor_data_set_type(sensor_data_list_col(buf, count), type);
				}
				else if(strcmp(node->columns[i].column_name, "DATA") == 0)	//保存数据
				{
					sensor_data_set_data(sensor_data_list_col(buf, count), node->columns[i].value.float_value);
				}
				else	//未知的数据类型
				{
					LOG_ERROR("db data no def col name :%s\n", node->columns[i].column_name);

					*data_list = NULL;
					*size = 0;
					db_col_select_res_free(all_data);
					free(buf);
					return;
				}
			}

			node = node->next;
			count++;
		}
	
		/*只保留使用的空间*/
		buf_size = count;
		int *tmp = realloc(buf, buf_size * sensor_data_size());
		LOG_DEBUG("realloc less count:%ld buf_size:%ld\n", count, buf_size);
		if (!tmp)
		{
			LOG_DEBUG("ERROR realloc less  fail count:%ld buf_size:%ld\n", count, buf_size);

			*data_list = NULL;
			*size = 0;
			db_col_select_res_free(all_data);
			free(buf);
			return;
		}
		else
		{
			buf = (sensor_data_t*)tmp;
			*data_list = buf;
			*size = buf_size;
			db_col_select_res_free(all_data);
		}
	}
}

/***************************************************************
 * Name:	 app_sensor_data_free_get_data()
 * Input : data_list 数据列表 size 参数个数
 * Output: void
 * Return: void
 * Author: hwl
 * Revise: V1.0
 * Description: 释放数据列表
 ***************************************************************/
void app_sensor_data_free_get_data(sensor_data_t* data_list, size_t count)
{
	free(data_list);
}

/***************************************************************
 * Name:	 app_sensor_data_init()
 * Input : NULL
 * Output: void
 * Return: -1 失败 0成功
 * Author: hwl
 * Revise: V1.0
 * Description: 传感器数据初始化
 ***************************************************************/
int app_sensor_data_init(void)
{
	/*初始化数据库*/
	g_db = sensor_data_db_init(DB_PATH);
	if(g_db == NULL)
	{
		LOG_ERROR("open g_db error\r\n");
		return -1;
	}
	else
	{
		/*初始化表*/
		if(sensor_data_table_find(g_db, TABLE_NAME) == -1)
		{
			LOG_DEBUG("sensor data create table\n");
			sensor_data_table_init(g_db, TABLE_NAME);
		}
		
		/*插入数据*/
		sensor_data_t* data = sensor_data_create("1712481234", CO2, 12.34);
		app_sensor_data_add_data(data);
		sensor_data_destroy(data);

		data = sensor_data_create("1712480123", TEMP, 23.45);
		struct tm custom_time = {
			.tm_year = 2024 - 1900,	// 2024 年
			.tm_mon = 9,						// 10 月
			.tm_mday = 1,						// 1 日
			.tm_hour = 12,					// 12 时
			.tm_min = 30,						// 30 分
			.tm_sec = 45,						// 45 秒
			.tm_isdst = -1,					// 自动判断夏令时
		};
		sensor_data_set_custom_date(data, mktime(&custom_time));
		app_sensor_data_add_data(data);
		sensor_data_destroy(data);
		
		data = sensor_data_create("1712480012", O2, -12.34);
		app_sensor_data_add_data(data);
		sensor_data_destroy(data);
	}

	// drv_db_close_db(g_db);
	return 0;
}

/***************************************************************
 * Name:	 string_to_time()
 * Input : str 时间字符串
 * Output: void
 * Return: time_t 转换成功 -1转换失败
 * Author: hwl
 * Revise: V1.0
 * Description: 时间字符串转换为time_t
 ***************************************************************/
static time_t string_to_time(const char* str)
{
	struct tm tm = {0};
	int year, month, day, hour, min, sec;

	// 解析字符串格式（例如 "2023-10-05 14:30:00"）
	if (sscanf(str, "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &min, &sec) != 6)
	{
		return (time_t)-1; // 解析失败
	}

	tm.tm_year = year - 1900;	// 年份从 1900 开始
	tm.tm_mon = month - 1;		// 月份 0-11
	tm.tm_mday = day;
	tm.tm_hour = hour;
	tm.tm_min = min;
	tm.tm_sec = sec;
	tm.tm_isdst = -1;					// 自动判断夏令时

	return mktime(&tm);
}